package com.mes.schedule.domain;

import java.awt.Color;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.annotations.GenericGenerator;

import com.mes.basicdata.domain.OperationDevice;
import com.mes.common.domain.BasicModel;
import com.mes.schedule.sbt.TaskSink;
import com.mes.schedule.util.ColorMap;
/**
 * 调度方案
 * date: Jun 22, 2015 11:08:28 AM <br/>  
 * @author Administrator  
 * @version   
 * @since JDK 1.6
 */

@Entity
@org.hibernate.annotations.Entity(dynamicInsert=false,dynamicUpdate=false)
@Table(name = "T_SCHEDULE_HEADER")

public class ScheduleScheme extends BasicModel implements Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private final static Log log = LogFactory.getLog(ScheduleScheme.class);
	/** SCHEDULESTATE for the schedule scheme */
	
	/**
	 * 调度方案状态--打开
	 */
	public final static int SCHEDULESTATE_OPENED = 100;
	/**
	 * 调度方案状态--关闭
	 */
	public final static int SCHEDULESTATE_CLOSED = 200;
	/**
	 * 调度方案状态--定时执行中
	 */
	public final static int SCHEDULESTATE_TIMING = 600;
	/**
	 * 调度方案状态--运行
	 */	
	public final static int SCHEDULESTATE_RUNNING = 2;
	/**
	 * 过滤班产任务的未来天数
	 */
	@Transient
	protected Integer shiftPlanDays = 5;
	public Integer getShiftPlanDays() {
		return shiftPlanDays;
	}

	public void setShiftPlanDays(Integer shiftPlanDays) {
		this.shiftPlanDays = shiftPlanDays;
	}
	
	@Id
	@GenericGenerator(name="uuid", strategy="assigned")
	@Column(name="UUID")
	private String uuid;

	public String getUuid() {
		return uuid;
	}

	public void setUuid(String uuid) {
		this.uuid = uuid;
	}

	/** basic information for the schedule scheme */
	@Column(name = "SCHEDULEUID")
	protected String scheduleUid;
	
	@Column(name = "SCHEDULENAME")
	protected String scheduleName;
	
	@Column(name = "DEPTID")
	protected String deptUid;
	
	@Column(name = "SCHEDULETYPE", precision = 10, scale = 0)
	protected Integer scheduleType;
	
	@Column(name = "SCHEDULESTATE", precision = 10, scale = 0)
	protected Integer scheduleState;

	/** parameters for the calculating process */
	
	@Column(name = "PLANSTART", length = 7)
	protected Date planStart;
	@Column(name = "PLANFINISH", length = 7)
	protected Date planFinish;
	
	@Transient
	protected Integer totalSegement;// 总共支持的时间段数，暂时不可以扩展
	
	@Column(name = "SCHEDULESTART", length = 7)
	protected Date scheduleStart;
	@Column(name = "SCHEDULEFINISH", length = 7)
	protected Date scheduleFinish;
	
	@Column(name = "SCHEDULEINTERVAL", precision = 10, scale = 0)
	protected Integer scheduleInterval = 15;
	
	@Column(name = "MAXOVERLAP", precision = 10)
	protected Double maxOverlap = 0.1;// 最大系数重叠
	
	@Column(name = "SLACKFACTOR", precision = 10, scale = 0)
	protected Integer slackType;
	
	@Column(name = "UTILIZEDAYS", precision = 10, scale = 0)
	protected Integer scheduleDays=30;

	/**
	 * 每个任务最多迭代次数
	 */ 
	@Transient
	protected int operationTaskMaxScheduleCount = 1000;

	/**
	 * 重点观察天数--对设备而言
	 */ 
	@Column(name = "WATCHDAYS", precision = 10, scale = 0)
	protected Integer watchDays = 10;
	
	@Transient
	protected Date watchFinish;

	/** parameters for the overtime */
	@Column(name = "ALLOWAUTOOVERTIME", precision = 1, scale = 0)
	protected Boolean allowAutoOvertime;
	
	@Column(name = "OVERTIMETASKLEVEL", precision = 1, scale = 0)
	protected Integer overtimeTaskLevel;
	
	@Column(name = "OVERTIMESLACK", precision = 10)
	protected Double overtimeSlack;


	/**
	 * 允许自动平顺
	 */	
	@Column(name = "ALLOWAUTOPS", precision = 1, scale = 0)
	protected Boolean allowAutoPS;
	/**
	 * 自动平顺任务等级
	 */		
	@Column(name = "PSTASKLEVEL", precision = 1, scale = 0)
	protected Integer autoPSTaskLevel;
	/**
	 * 自动平顺松弛，低于该松弛系数时，允许自动考虑平顺操作
	 */		
	@Column(name = "AUTOPSSLACK", precision = 10)
	protected Double autoPSSlack;
	/**
	 * 是否应用自动流水
	 */
	@Column(name = "ALLOWCOMPRESSNET", precision = 1, scale = 0)
	protected Boolean allowAutoFlow;
	/**
	 * 自动流水松弛系数
	 */
	@Column(name = "COMPRESSNETSLACK", precision = 10)
	protected Double autoFlowSlack;	
	/**
	 * 允许自动根据反馈情况自动刷新工时
	 */
	@Column(name = "ALLOW_AUTO_REGRESS_HOUR", precision = 1, scale = 0)
	protected Boolean allowAutoRegressHour;
	/**
	 * 允许成组加工
	 */
	@Column(name = "ALLOWGROUP", precision = 1, scale = 0)
	protected Boolean allowGroup;
	/**
	 * 等待警示天数
	 */
	@Column(name = "WARNINGWAITDAYS", precision = 10)
	protected Integer warningWaitDays;

	@Column(name = "LOCKDISPATCHTASK", precision = 10)
	protected Boolean lockDispatchTask;

	@Column(name = "LAST_UPDATE_TIME", precision = 10)
	protected Date lastUpdateTime;
	
	@Column(name = "DEFAULT_CALENDAR_UID", precision = 10)
	private String defaultCalendarUid;
	
	@Transient
	private SCalendar defaultCalendar;

	/**
	 * 是否允许投入控制
	 * 暂时也还没有正式使用
	 */
	@Transient
	private Boolean allowThrowInControl = false;

	/**
	 * 投入控制松弛系数
	 */
	@Column(name = "CONVERSESLACK", precision = 10)
	private Double throwInControSlack;
	
	@Transient
	private boolean allowDeviceQueueInterrupt = true;
	/**
	 * 是否应用最短剩余时间优先规则
	 */
	@Column(name = "ALLOW_LEVEL_SPLIT")
	private Boolean applySTF ;
	
	@Column(name = "DISPATCH_DAYS", precision = 10)
	private Integer dispatchDays;
	/**
	 * 是否有效
	 */ 
	@Column(name = "ISINEFFECT", precision = 1, scale = 0)
	private Boolean effective;
	/**
	 * 自动完成之前的工序
	 */
	@Column(name = "MINSPLITSLACK", precision = 10)
	private Boolean allowAutoFinishBeforeTask;
	/**
	 * 是否继承主制车间的优先级、松弛率信息
	 */
	@Column(name = "ALLOW_INIT_SPLIT")
	private Boolean inheritCoTaskPriority;

	// volatile
	@Transient
	protected volatile Integer totalAssignCount;
	@Transient
	protected volatile Integer totalCancelAssignCount;

	

	// 这样新序列化处的方案只用于调度，没有必要保持
	/**
	 *  调度中所有工序任务Map
	 */
	@Transient
	protected Map<String, SOperationTask> allOperationTaskMap;
	/**
	 *  调度中所有零件任务Map
	 */
	@Transient
	protected Map<String, SPartTask> allPartTaskMap; 
	/**
	 *  调度中工序之间的链接Map
	 */
	@Transient
	protected Map<String, SOperationLink> allOperationLinkMap;

	// part tasks in scheduling
	// protected List<SPartTask> addedPartTaskList; //added part tasks
	/**
	 * 分批的零件任务Map
	 */	
	@Transient
	protected List<SPartTask> splitedPartTaskList;
	/**
	 * 零件任务Set
	 */	
	@Transient
	protected Set<SPartTask> schedulePartTasks;

	/**
	 * 协作任务Map
	 */
	@Transient
	protected Map<String, SOperationTask> coTaskMap; // cooperation tasks in
	// scheduling
	@Transient
	protected List<SOperationTask> scheduleTempTaskList;
	
	@Transient
	protected List<SOperationTask> groupTaskList;
	
	@Transient
	protected List<SOperationLink> additionalOperationLinks;
	/**
	 * 设备Map
	 */
	@Transient
	protected Map<String, SDevice> deviceMap;
	/**
	 * 工作中心Map
	 */
	@Transient
	protected Map<String, SWorkCenter> workCenterMap;
	/**
	 * 日历Map
	 */
	@Transient
	protected Map<String, SCalendar> calendarMap;

	/**
	 * 保存调度中的设备限制Map
	 */
	@Transient
	protected Map<String, List<OperationDevice>> operationDeviceMap;

	// //临时分派顺序，一个任务分派之前或者之后另外一个任务必须马上分派
	// protected List<SVirtualLink> tempAssnSortLinks;

	/**
	 * 工序任务Set  准备好的任务排序，当前待分派任务
	 *	可以用作暂停等操作
	 *	所有线程共享 volatile
	 */ 	
	@Transient
	protected volatile TreeSet<SOperationTask> readyTaskS;

	/**
	 *  虚拟协作工作中心
	 */
	@Transient
	protected SWorkCenter virtualCoWorkCenter;

	/**
	 * 虚拟协作设备
	 */
	@Transient
	protected SDevice virtualCoDevice;
	
	/**
	 * 调度最长等待时间
	 */
	@Transient
	protected int maxScheduleWaitMinutes;


	/**
	 * 工序任务排序的比较器
	 * lqm todo 将来应该放在专门的规则调度算法中
	 */
	@Transient
	protected Comparator<SOperationTask> operationTaskComparator;


	/**
	 * 调度当前时间, schedulestart之当前时间可能有一些已经完成的任务
	 * 可以用于仿真推进
	 */
	@Transient
	private Date scheduleCurrentTime;

	// 只在tptAssignManager中应用，应该移出
	// 仅用于设备是否全部调度完的锁
	// volatile用于声明简单变量
	@Transient
	public volatile boolean allDeviceFinishObjectLock;
	
	
	
	protected transient boolean persistence=true;
	/**
	 * 工序任务Set
	 */
	@Transient
	private Set<SOperationTask> scheduleOperationTasks;
	
	public final static String SCHEDULE_TARGET_TWT="TWT";
	public final static String SCHEDULE_TARGET_TT="TT";
	public final static String SCHEDULE_TARGET_MAKESPAN="MAKESPAN";
	
	@Transient
	protected String scheduleTargetType;
	
	@Transient
	protected String algorithmName; 
	
	/**
	 * 仅用做临时变量，表明每个任务距离最终节点的距离，由于网络复杂，所以一个
	 * 任务会存在多个节点
	 * lqm todo
	 * 对临时变量应该形成通用机制
	 */
	@Transient
	protected Map<String, Set<TaskSink>> calTaskSinkMap;
	/**
	 * 颜色集合，用于fullCalendar任务展示
	 */
	@Transient
	protected Map<String, Color> colorMap = new HashMap<String, Color>();
	/**
	 * 用于展示零件时的颜色，在新添加零件时需要动态的更新
	 * @author lcs
	 * @param scheme
	 */
	public void initColorMap() {
		// TODO Auto-generated method stub
		ColorMap map = new ColorMap();
		int i = 0;
		// 使用调度零件任务来初始化颜色
		for (SPartTask partTask : this.schedulePartTasks) {
			i++;
			String colorKey = partTask.getTaskUid();
			if (i >= 50) {
				int r = (int) (Math.random() * 255);
				int g = (int) (Math.random() * 255);
				int b = (int) (Math.random() * 255);
				this.colorMap.put(colorKey, new Color(r, g, b));
			} else {
				this.colorMap.put(colorKey, map.colorMap.get(i));
			}
		}
	}


	/**
	 * 调度结果形成的加班任务列表
	 */
	@Transient
	protected List<ScheduleOverTime> overTimeList;

	/**
	 * 零件关键等级
	 */
	@Column(name="PARTCRITICAL_LEVEL")
	protected Integer partCriticalLevel;
	
	@Column(name="CRITICAL_LEVEL")
	protected Integer criticalLevel;

	@Column(name="SCHEMETYPE",length=10)
	protected String schemeType;
	
	/**
	 * @author lcs
	 */
	// 基准计划唯一号
	@Column(name="BASE_SCHEDULE_UID")
	private String baseScheduleUid;
	
	public Integer getBaseScheduleMode() {
		return baseScheduleMode;
	}

	public void setBaseScheduleMode(Integer baseScheduleMode) {
		this.baseScheduleMode = baseScheduleMode;
	}

	@Column(name="BASE_CONSTRAINT_MODE")
	private Integer baseScheduleMode;
	
	public String getBaseScheduleUid() {
		return baseScheduleUid;
	}

	public void setBaseScheduleUid(String baseScheduleUid) {
		this.baseScheduleUid = baseScheduleUid;
	}

	public String getSchemeType() {
		return schemeType;
	}

	public void setSchemeType(String schemeType) {
		this.schemeType = schemeType;
	}

	public Integer getCriticalLevel() {
		return criticalLevel;
	}

	public void setCriticalLevel(Integer criticalLevel) {
		this.criticalLevel = criticalLevel;
	}

	public Integer getPartCriticalLevel() {
		return partCriticalLevel;
	}

	public void setPartCriticalLevel(Integer partCriticalLevel) {
		this.partCriticalLevel = partCriticalLevel;
	}
	public Map<String, Set<TaskSink>> getCalTaskSinkMap() {
		return calTaskSinkMap;
	}

	public void setCalTaskSinkMap(Map<String, Set<TaskSink>> calTaskSinkMap) {
		this.calTaskSinkMap = calTaskSinkMap;
	}

	public String getAlgorithmName() {
		return algorithmName;
	}

	public void setAlgorithmName(String algorithmName) {
		this.algorithmName = algorithmName;
	}

	public Set<SPartTask> getSchedulePartTasks() {
		return schedulePartTasks;
	}

	public Set<SOperationTask> getScheduleOperationTasks() {
		return scheduleOperationTasks;
	}

	public void setSchedulePartTasks(Set<SPartTask> schedulePartTasks) {
		this.schedulePartTasks = schedulePartTasks;
	}

	public void setScheduleOperationTasks(
			Set<SOperationTask> scheduleOperationTasks) {
		this.scheduleOperationTasks = scheduleOperationTasks;
	}

	// 让这个参数化
	// 主要用于仿真测试
	// todo
	// 仿真功能暂时取消
	// 让其保证调度过程中的时间一致性
	// 让尽量少的地方取当前时间
	public Date getScheduleCurrentTime() {
		return this.scheduleCurrentTime == null ? new Date()
				: this.scheduleCurrentTime;
	}

	public void setScheduleCurrentTime(Date scheduleCurrentTime) {
		this.scheduleCurrentTime = scheduleCurrentTime;
	}

	public SDevice getVirtualCoDevice() {
		return virtualCoDevice;
	}

	public void setVirtualCoDevice(SDevice virtualCoDevice) {
		this.virtualCoDevice = virtualCoDevice;
	}

	public SWorkCenter getVirtualCoWorkCenter() {
		return virtualCoWorkCenter;
	}

	public void setVirtualCoWorkCenter(SWorkCenter virtualCoWorkCenter) {
		this.virtualCoWorkCenter = virtualCoWorkCenter;
	}

	/**
	 * 构造方法
	 */
	public ScheduleScheme() {
		allowAutoRegressHour = false;
		allPartTaskMap = new HashMap<String, SPartTask>();// 缺省容量为1000
		allOperationTaskMap = new HashMap<String, SOperationTask>();// 缺省容量为1000
		allOperationLinkMap = new HashMap<String, SOperationLink>();// 缺省容量为1000
		// allOperationTaskMap= new Map<String,
		// SOperationTask>(10000);//缺省容量为10000
		operationDeviceMap = new HashMap<String, List<OperationDevice>>();
		scheduleOperationTasks = new HashSet<SOperationTask>();
		schedulePartTasks = new HashSet<SPartTask>();

		splitedPartTaskList = new ArrayList<SPartTask>();

		groupTaskList = new ArrayList<SOperationTask>();
		calendarMap = new HashMap<String, SCalendar>();
		coTaskMap = new HashMap<String, SOperationTask>();

		scheduleTempTaskList = new ArrayList<SOperationTask>();

		deviceMap = new HashMap<String, SDevice>();
		workCenterMap = new HashMap<String, SWorkCenter>();
		
		this.totalAssignCount=0;
		this.totalCancelAssignCount=0;

		if(this.scheduleState==null)
			this.scheduleState=ScheduleScheme.SCHEDULESTATE_OPENED;

	}

	/**
	 * @return the scheduleUid
	 */
	public String getScheduleUid() {
		return scheduleUid;
	}

	/**
	 * @param scheduleUid
	 *            the scheduleUid to set
	 */
	public void setScheduleUid(String scheduleUid) {
		this.scheduleUid = scheduleUid;
	}

	/**
	 * @return the scheduleName
	 */
	public String getScheduleName() {
		return scheduleName;
	}

	/**
	 * @param scheduleName
	 *            the scheduleName to set
	 */
	public void setScheduleName(String scheduleName) {
		this.scheduleName = scheduleName;
	}

	/**
	 * @return the deptUid
	 */
	public String getDeptUid() {
		return deptUid;
	}

	/**
	 * @param deptUid
	 *            the deptUid to set
	 */
	public void setDeptUid(String deptUid) {
		this.deptUid = deptUid;
	}

	/**
	 * @return the planStart
	 */
	public Date getPlanStart() {
		return planStart;
	}

	/**
	 * @param planStart
	 *            the planStart to set
	 */
	public void setPlanStart(Date planStart) {
		this.planStart = planStart;
	}

	/**
	 * @return the planFinish
	 */
	public Date getPlanFinish() {
		return planFinish;
	}

	/**
	 * @param planFinish
	 *            the planFinish to set
	 */
	public void setPlanFinish(Date planFinish) {
		this.planFinish = planFinish;
	}

	/**
	 * @return the scheduleStart
	 */
	public Date getScheduleStart() {
		return scheduleStart;
	}

	/**
	 * @param scheduleStart
	 *            the scheduleStart to set
	 */
	public void setScheduleStart(Date scheduleStart) {
		this.scheduleStart = scheduleStart;
	}

	/**
	 * @return the scheduleFinish
	 */
	public Date getScheduleFinish() {
		return scheduleFinish;
	}

	/**
	 * @param scheduleFinish
	 *            the scheduleFinish to set
	 */
	public void setScheduleFinish(Date scheduleFinish) {
		this.scheduleFinish = scheduleFinish;
	}

	/**
	 * @return the scheduleInterval
	 */
	public Integer getScheduleInterval() {
		return scheduleInterval;
	}

	/**
	 * @param scheduleInterval
	 *            the scheduleInterval to set
	 */
	public void setScheduleInterval(Integer scheduleInterval) {
		this.scheduleInterval = scheduleInterval;
	}

	/**
	 * @return the maxOverlap
	 */
	public Double getMaxOverlap() {
		return maxOverlap;
	}

	/**
	 * @param maxOverlap
	 *            the maxOverlap to set
	 */
	public void setMaxOverlap(Double maxOverlap) {
		this.maxOverlap = maxOverlap;
	}

	/**
	 * @return the slackType
	 */
	public Integer getSlackType() {
		return slackType;
	}

	/**
	 * @param slackType
	 *            the slackType to set
	 */
	public void setSlackType(Integer slackType) {
		this.slackType = slackType;
	}

	/**
	 * @return the scheduleDays
	 */
	public Integer getScheduleDays() {
		return scheduleDays;
	}

	/**
	 * @param scheduleDays
	 *            the scheduleDays to set
	 */
	public void setScheduleDays(Integer scheduleDays) {
		this.scheduleDays = scheduleDays;
	}

	/**
	 * @return the watchDays
	 */
	public Integer getWatchDays() {
		return watchDays;
	}

	/**
	 * @param watchDays
	 *            the watchDays to set
	 */
	public void setWatchDays(Integer watchDays) {
		this.watchDays = watchDays;
	}

	/**
	 * @return the allowAutoOvertime
	 */
	public Boolean getAllowAutoOvertime() {
		return allowAutoOvertime;
	}

	/**
	 * @param allowAutoOvertime
	 *            the allowAutoOvertime to set
	 */
	public void setAllowAutoOvertime(Boolean allowAutoOvertime) {
		this.allowAutoOvertime = allowAutoOvertime;
	}

	/**
	 * @return the overtimeTaskLevel
	 */
	public Integer getOvertimeTaskLevel() {
		return overtimeTaskLevel;
	}

	/**
	 * @param overtimeTaskLevel
	 *            the overtimeTaskLevel to set
	 */
	public void setOvertimeTaskLevel(Integer overtimeTaskLevel) {
		this.overtimeTaskLevel = overtimeTaskLevel;
	}

	/**
	 * @return the overtimeSlack
	 */
	public Double getOvertimeSlack() {
		return overtimeSlack;
	}

	/**
	 * @param overtimeSlack
	 *            the overtimeSlack to set
	 */
	public void setOvertimeSlack(Double overtimeSlack) {
		this.overtimeSlack = overtimeSlack;
	}

	/**
	 * @return the allowAutoPS
	 */
	public Boolean getAllowAutoPS() {
		return allowAutoPS;
	}

	/**
	 * @param allowAutoPS
	 *            the allowAutoPS to set
	 */
	public void setAllowAutoPS(Boolean allowAutoPS) {
		this.allowAutoPS = allowAutoPS;
	}

	/**
	 * @return the autoPSTaskLevel
	 */
	public Integer getAutoPSTaskLevel() {
		return autoPSTaskLevel;
	}

	/**
	 * @param autoPSTaskLevel
	 *            the autoPSTaskLevel to set
	 */
	public void setAutoPSTaskLevel(Integer autoPSTaskLevel) {
		this.autoPSTaskLevel = autoPSTaskLevel;
	}

	/**
	 * @return the autoPSSlack
	 */
	public Double getAutoPSSlack() {
		return autoPSSlack;
	}

	/**
	 * @param autoPSSlack
	 *            the autoPSSlack to set
	 */
	public void setAutoPSSlack(Double autoPSSlack) {
		this.autoPSSlack = autoPSSlack;
	}

	/**
	 * @return the allowGroup
	 */
	public Boolean getAllowGroup() {
		return allowGroup;
	}

	/**
	 * @param allowGroup
	 *            the allowGroup to set
	 */
	public void setAllowGroup(Boolean allowGroup) {
		this.allowGroup = allowGroup;
	}

	/**
	 * @return the warningWaitDays
	 */
	public Integer getWarningWaitDays() {
		return warningWaitDays;
	}

	/**
	 * @param warningWaitDays
	 *            the warningWaitDays to set
	 */
	public void setWarningWaitDays(Integer warningWaitDays) {
		this.warningWaitDays = warningWaitDays;
	}

	/**
	 * @return the lockDispatchTask
	 */
	public Boolean getLockDispatchTask() {
		return lockDispatchTask;
	}

	/**
	 * @param lockDispatchTask
	 *            the lockDispatchTask to set
	 */
	public void setLockDispatchTask(Boolean lockDispatchTask) {
		this.lockDispatchTask = lockDispatchTask;
	}

	/**
	 * @return the partTaskList
	 */
	// public List<SPartTask> getSchedulePartTasks() {
	// if(this.allPartTaskMap==null)return null;
	// List<SPartTask> partTaskList=new ArrayList<SPartTask>();
	// for(SPartTask sp:this.allPartTaskMap.values())
	// {
	// if(sp.taskScheduleState==SPartTask.TASKSCHEDULESTATE_STARTED)
	// partTaskList.add(sp);
	// }
	// return partTaskList;
	// }
	// /**
	// * 返回已经进入调度的工序任务列表
	// * todo lqm
	// * 应该避免频繁过滤，
	// *
	// * @return the partTaskList
	// */
	// public List<SOperationTask> getScheduleOperationTasks() {
	// if(this.allOperationTaskMap==null)return null;
	// List<SOperationTask> operationTaskList=new ArrayList<SOperationTask>();
	// //应该用 Collections进行分析
	// for(SOperationTask operationTask:this.allOperationTaskMap.values())
	// {
	// if(log.isDebugEnabled())
	// {
	// if(operationTask.getTaskUid().equals("d256227b-d460-44f6-9068-8ca9fe38cb4e"))
	// log.debug(operationTask.toFriendlyString());
	//
	// }
	//			
	// if(operationTask.getTaskScheduleState()
	// ==SOperationTask.TASKSCHEDULESTATE_STARTED)
	// operationTaskList.add(operationTask);
	// }
	// return operationTaskList;
	// }
	/**
	 * @return the splitedPartTaskList
	 */
	public List<SPartTask> getSplitedPartTaskList() {
		return splitedPartTaskList;
	}

	/**
	 * @param splitedPartTaskList
	 *            the splitedPartTaskList to set
	 */
	public void setSplitedPartTaskList(List<SPartTask> splitedPartTaskList) {
		this.splitedPartTaskList = splitedPartTaskList;
	}

	/**
	 * @return the combineBatchList
	 */
	public List<SPartTask> getCombineBatchList() {
		if (this.allPartTaskMap == null)
			return null;
		List<SPartTask> combineBatchList = new ArrayList<SPartTask>();
		for (SPartTask sp : this.allPartTaskMap.values()) {
			if (sp.getTaskScheduleType() == SPartTask.TASKSCHEDULETYPE_COMBINEBATCH)
				combineBatchList.add(sp);
		}
		return combineBatchList;

	}

	public Map<String, SOperationTask> getCoTaskMap() {
		return coTaskMap;
	}

	public void setCoTaskMap(Map<String, SOperationTask> coTaskMap) {
		this.coTaskMap = coTaskMap;
	}

	public List<SOperationTask> getScheduleTempTaskList() {
		return scheduleTempTaskList;
	}

	public void setScheduleTempTaskList(
			List<SOperationTask> scheduleTempTaskList) {
		this.scheduleTempTaskList = scheduleTempTaskList;
	}

	/**
	 * @return the deviceMap
	 */
	public Map<String, SDevice> getDeviceMap() {
		return deviceMap;
	}

	/**
	 * @param deviceMap
	 *            the deviceMap to set
	 */
	public void setDeviceMap(Map<String, SDevice> deviceMap) {
		this.deviceMap = deviceMap;
	}

	/**
	 * @return the scheduleType
	 */
	public Integer getScheduleType() {
		return scheduleType;
	}

	/**
	 * @param scheduleType
	 *            the scheduleType to set
	 */
	public void setScheduleType(Integer scheduleType) {
		this.scheduleType = scheduleType;
	}

	/**
	 * @return the scheduleState
	 */
	public Integer getScheduleState() {
		return scheduleState;
	}

	/**
	 * @param scheduleState
	 *            the scheduleState to set
	 */
	public void setScheduleState(Integer scheduleState) {
		this.scheduleState = scheduleState;
	}

	/**
	 * @return the calendarMap
	 */
	public Map<String, SCalendar> getCalendarMap() {
		return calendarMap;
	}

	/**
	 * @param calendarMap
	 *            the calendarMap to set
	 */
	public void setCalendarMap(Map<String, SCalendar> calendarMap) {
		this.calendarMap = calendarMap;
	}

	// public Object clone() {
	// Object obj = null;
	// try {
	// obj = super.clone();
	// } catch (CloneNotSupportedException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	// return obj;
	// }

	/*
	 * 通过工序任务的uuid查找工序任务 暂时只实现了在调度零件任务集合中的查找
	 */
	// public SOperationTask findOperationTaskByUid(String taskUid)
	// {
	// for (SPartTask partTask : partTaskList)
	// for (SOperationTask operTask : partTask.getOperationTaskList())
	// if (operTask.getTaskUid().equals(taskUid)) return operTask;
	// return null;
	// }
	public Integer getTotalSegement() {
		return totalSegement;
	}

	public void setTotalSegement(Integer totalSegement) {
		this.totalSegement = totalSegement;
	}

	/*
	 * 设置总调度时间段
	 */
	public void calTotalSegement() {
		this.totalSegement = (int) ((scheduleFinish.getTime() - scheduleStart
				.getTime()) / 60000 / scheduleInterval);

	}

	public Map<String, SOperationTask> getAllOperationTaskMap() {
		return allOperationTaskMap;
	}

	public Map<String, SPartTask> getAllPartTaskMap() {
		return allPartTaskMap;
	}

	public void setAllOperationTaskMap(
			Map<String, SOperationTask> allOperationTaskMap) {
		this.allOperationTaskMap = allOperationTaskMap;
	}

	public void setAllPartTaskMap(Map<String, SPartTask> allPartTaskMap) {
		this.allPartTaskMap = allPartTaskMap;
	}

	public List<SOperationLink> getAdditionalOperationLinks() {
		return additionalOperationLinks;
	}

	public void setAdditionalOperationLinks(
			List<SOperationLink> additionalOperationLinks) {
		this.additionalOperationLinks = additionalOperationLinks;
	}

	public Map<String, SOperationLink> getAllOperationLinkMap() {
		return allOperationLinkMap;
	}

	public void setAllOperationLinkMap(
			Map<String, SOperationLink> allOperationLinkMap) {
		this.allOperationLinkMap = allOperationLinkMap;
	}

	public Date getLastUpdateTime() {
		return lastUpdateTime;
	}

	public void setLastUpdateTime(Date lastUpdateTime) {
		this.lastUpdateTime = lastUpdateTime;
	}

	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return this.uuid + " " + this.scheduleName == null ? ""
				: this.scheduleName;
	}

	public Map<String, List<OperationDevice>> getOperationDeviceMap() {
		return operationDeviceMap;
	}

	public void setOperationDeviceMap(
			Map<String, List<OperationDevice>> operationDeviceMap) {
		
		//居然放了这样一个大错  operationDeviceMap=operationDeviceMap,写成了一个恒等式
		this.operationDeviceMap = operationDeviceMap;
	}

	public String getDefaultCalendarUid() {
		return defaultCalendarUid;
	}

	public void setDefaultCalendarUid(String defaultCalendarUid) {
		this.defaultCalendarUid = defaultCalendarUid;
	}

	// todo
	// 应该改成schemeManager中的static方法
	// 其实关于时间也可以采用日历时间本身的long属性，
	// 调度时间动态增长

	// 根据当前时间的微秒值获取时段
	public Integer calSegementFromDate(long dtTime) {
		long scheduleStartTime = this.scheduleStart.getTime();
		if (dtTime <= scheduleStartTime)
			return 0;
		int seg = (int) Math.round((dtTime - scheduleStartTime)
				/ (60000 * this.scheduleInterval));
		return seg > this.totalSegement ? this.totalSegement : seg;
	}

	public Integer calSegementFromDate(Date dt) {
		if (dt == null || dt.before(this.scheduleStart))
			return 0;
		int seg = (int) Math.round((dt.getTime() - this.scheduleStart.getTime())
						/ (60000 * this.scheduleInterval));
		return seg > this.totalSegement ? this.totalSegement : seg;
	}

	public Date calDateFromSegement(int segement) {
		long start = this.scheduleStart.getTime();
		int interval = this.scheduleInterval;

		return new Date((long) segement * interval * 60000 + start);
	}

	public TreeSet<SOperationTask> getReadyTaskS() {
		return readyTaskS;
	}

	public void setReadyTaskS(TreeSet<SOperationTask> readyTaskS) {
		this.readyTaskS = readyTaskS;
	}

	public Boolean getAllowAutoRegressHour() {
		return allowAutoRegressHour;
	}

	public void setAllowAutoRegressHour(Boolean allowAutoRegressHour) {
		this.allowAutoRegressHour = allowAutoRegressHour;
	}

	public Date getWatchFinish() {
		return watchFinish;
	}

	public void setWatchFinish(Date watchFinish) {
		this.watchFinish = watchFinish;
	}

	public boolean isAllowDeviceQueueInterrupt() {
		return allowDeviceQueueInterrupt;
	}

	public void setAllowDeviceQueueInterrupt(boolean allowDeviceQueueInterrupt) {
		this.allowDeviceQueueInterrupt = allowDeviceQueueInterrupt;
	}

	public SCalendar getDefaultCalendar() {
		return defaultCalendar;
	}

	public void setDefaultCalendar(SCalendar defaultCalendar) {
		this.defaultCalendar = defaultCalendar;
	}

	public Integer getDispatchDays() {
		return dispatchDays;
	}

	public void setDispatchDays(Integer dispatchDays) {
		this.dispatchDays = dispatchDays;
	}

	public List<SOperationTask> getGroupTaskList() {
		return groupTaskList;
	}

	public void setGroupTaskList(List<SOperationTask> groupTaskList) {
		this.groupTaskList = groupTaskList;
	}

	public Map<String, SWorkCenter> getWorkCenterMap() {
		return workCenterMap;
	}

	public void setWorkCenterMap(Map<String, SWorkCenter> workCenterMap) {
		this.workCenterMap = workCenterMap;
	}

	public Boolean getEffective() {
		return effective;
	}

	public void setEffective(Boolean effective) {
		this.effective = effective;
	}

	public Comparator<SOperationTask> getOperationTaskComparator() {
		return operationTaskComparator;
	}

	public void setOperationTaskComparator(
			Comparator<SOperationTask> operationTaskComparator) {
		this.operationTaskComparator = operationTaskComparator;
	}

	public Boolean getAllowThrowInControl() {
		return allowThrowInControl;
	}

	public void setAllowThrowInControl(Boolean allowThrowInControl) {
		this.allowThrowInControl = allowThrowInControl;
	}

	public Double getThrowInControSlack() {
		return throwInControSlack;
	}

	public void setThrowInControSlack(Double throwInControSlack) {
		this.throwInControSlack = throwInControSlack;
	}

	public int getTotalAssignCount() {
		return totalAssignCount;
	}

	// 用多线程时保证同步

	public void addOneAssignCount() {
		synchronized (totalAssignCount) {
			this.totalAssignCount++;
		}

	}

	public int getTotalCancelAssignCount() {
		return totalCancelAssignCount;
	}

	public void addOneCancelAssignCount() {
		// synchronized (totalCancelAssignCount) {
		this.totalCancelAssignCount++;
		// }

	}

	public int getOperationTaskMaxScheduleCount() {
		return operationTaskMaxScheduleCount;
	}

	public void setOperationTaskMaxScheduleCount(
			int operationTaskMaxScheduleCount) {
		this.operationTaskMaxScheduleCount = operationTaskMaxScheduleCount;
	}

	public Boolean getAllowAutoFinishBeforeTask() {
		return allowAutoFinishBeforeTask == null ? false
				: allowAutoFinishBeforeTask;
	}

	public void setAllowAutoFinishBeforeTask(Boolean allowAutoFinishBeforeTask) {
		this.allowAutoFinishBeforeTask = allowAutoFinishBeforeTask;
	}

	public void setTotalAssignCount(Integer totalAssignCount) {
		this.totalAssignCount = totalAssignCount;
	}

	public void setTotalCancelAssignCount(Integer totalCancelAssignCount) {
		this.totalCancelAssignCount = totalCancelAssignCount;
	}

	public Boolean getInheritCoTaskPriority() {
		return inheritCoTaskPriority == null ? true : inheritCoTaskPriority;
	}

	public void setInheritCoTaskPriority(Boolean inheritCoTaskPriority) {
		this.inheritCoTaskPriority = inheritCoTaskPriority;
	}

	// public List<SVirtualLink> getTempAssnSortLinks() {
	// return tempAssnSortLinks;
	// }
	//
	// public void setTempAssnSortLinks(List<SVirtualLink> tempAssnSortLinks) {
	// this.tempAssnSortLinks = tempAssnSortLinks;
	// }

	// public List<SPartTask> getSchedulePartTasks() {
	// return schedulePartTaskList;
	// }
	//
	// public void setSchedulePartTaskList(List<SPartTask> schedulePartTaskList)
	// {
	// this.schedulePartTaskList = schedulePartTaskList;
	// }

	public void destroy() {
		try {
			// TODO Auto-generated method stub
			if (this.allPartTaskMap != null) {
				for (SPartTask partTask : this.allPartTaskMap.values()) {
					partTask.destroy();
				}
				this.allPartTaskMap.clear();
				this.allPartTaskMap = null;
			}
			
			if (this.allOperationTaskMap != null) {
				for (SOperationTask so : this.allOperationTaskMap.values()) {
					so.destroy();
				}
				this.allOperationTaskMap.clear();
				this.allOperationTaskMap = null;
			}

			if (this.allOperationLinkMap != null) {
				for (SOperationLink link : this.allOperationLinkMap.values()) {
					link.destroy();
				}

				this.allOperationLinkMap.clear();
				this.allOperationLinkMap = null;
			}
			
			if (this.scheduleOperationTasks != null) {
				this.scheduleOperationTasks.clear();
				this.scheduleOperationTasks = null;
			}

			if (this.deviceMap != null) {
				for (SDevice device : this.deviceMap.values()) {
					device.destroy();
				}
				this.deviceMap.clear();
				this.deviceMap = null;
			}

			if (this.calendarMap != null) {
				for (SCalendar calendar : this.calendarMap.values()) {
					calendar.destroy();
				}
				this.calendarMap.clear();
				this.calendarMap = null;
			}

			if (this.workCenterMap != null) {
				for (SWorkCenter workCenter : this.workCenterMap.values()) {
					//报错方法注销lcs
					//workCenter.destroy();
				}
				this.workCenterMap.clear();
				this.workCenterMap = null;
			}

			if (coTaskMap != null) {
				coTaskMap.clear();
				coTaskMap = null;
			}

			if (operationDeviceMap != null) {
				operationDeviceMap.clear();
				operationDeviceMap = null;
			}

			if (splitedPartTaskList != null)
				splitedPartTaskList = null;
			if (groupTaskList != null)
				groupTaskList = null;
			if (scheduleTempTaskList != null)
				scheduleTempTaskList = null;
		} catch (RuntimeException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	public Boolean getApplySTF() {
		return applySTF;
	}

	public void setApplySTF(Boolean applySTF) {
		this.applySTF = applySTF;
	}

	public Boolean getAllowAutoFlow() {
		return allowAutoFlow;
	}

	public void setAllowAutoFlow(Boolean allowAutoFlow) {
		this.allowAutoFlow = allowAutoFlow;
	}

	public Double getAutoFlowSlack() {
		return autoFlowSlack;
	}

	public void setAutoFlowSlack(Double autoFlowSlack) {
		this.autoFlowSlack = autoFlowSlack;
	}

	public boolean getPersistence() {
		return persistence;
	}
	public void setPersistence(boolean persistence) {
		this.persistence = persistence;
	}

	public int getMaxScheduleWaitMinutes() {
		return maxScheduleWaitMinutes;
	}

	public void setMaxScheduleWaitMinutes(int maxScheduleWaitMinutes) {
		this.maxScheduleWaitMinutes = maxScheduleWaitMinutes;
	}

	public String getScheduleTargetType() {
		return scheduleTargetType;
	}

	public void setScheduleTargetType(String scheduleTargetType) {
		this.scheduleTargetType = scheduleTargetType;
	}

	public List<ScheduleOverTime> getOverTimeList() {
		return overTimeList;
	}

	public void setOverTimeList(List<ScheduleOverTime> overTimeList) {
		this.overTimeList = overTimeList;
	}
	
	/**
	 * by lcs 添加用于ScheduleDeviceDataAccess
	 */
	@Transient
	protected String currentScheduleSchemeType;
	
	public String getCurrentScheduleSchemeType() {
		return currentScheduleSchemeType;
	}

	public void setCurrentScheduleSchemeType(String currentScheduleSchemeType) {
		this.currentScheduleSchemeType = currentScheduleSchemeType;
	}

	@Column(name = "SHIFT_DISTANCE",precision=10,scale=0)
	private Integer shiftDistance;
	public Integer getShiftDistance() {
		return shiftDistance;
	}

	public void setShiftDistance(Integer shiftDistance) {
		this.shiftDistance = shiftDistance;
	}
	
	
	
}
